package org.acghub.config;

import org.acghub.config.type.*;
import org.apache.commons.lang3.StringUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * @Desc
 * @Author miyuki4j
 * @Date 2025/7/24/星期四 13:52
 * @Version 1.0
 */
public class TypeFactory {

    private static final Map<String, Type> TYPES = new HashMap<>();

    static {
        register(new BoolType());
        register(new IntType());
        register(new LongType());
        register(new FloatType());
        register(new DoubleType());
        register(new StringType());
        register(new RewardType());
        register(new DateType());
    }


    private static void register(Type type) {
        TYPES.put(type.name(), type);
    }

    private static Type get(String name) {
        return TYPES.get(name);
    }

    private static Type getContainerType(String tokenType) {
        Type type;
        if (StringUtils.startsWith(tokenType, "list<") && StringUtils.endsWith(tokenType, ">")) {
            type = new ListType();
        } else if (StringUtils.startsWith(tokenType, "list2<") && StringUtils.endsWith(tokenType, ">")) {
            type = new List2Type();
        } else if (StringUtils.startsWith(tokenType, "set<") && StringUtils.endsWith(tokenType, ">")) {
            type = new HashSetType();
        } else if (StringUtils.startsWith(tokenType, "treeset<") && StringUtils.endsWith(tokenType, ">")) {
            type = new TreeSetType();
        } else if (StringUtils.startsWith(tokenType, "map<") && StringUtils.endsWith(tokenType, ">")) {
            type = new HashMapType();
        } else if (StringUtils.startsWith(tokenType, "treemap<") && StringUtils.endsWith(tokenType, ">")) {
            type = new TreeSetType();
        } else {
            throw new TypeParseException("invalid container type: " + tokenType);
        }
        return type;
    }


    static Type parseUnsafe(TableField field, String type, String delimiters) {
        Type javaType = get(type);
        if (type != null) {
            javaType.parse(field, type, delimiters);
            return javaType;
        }
        javaType = getContainerType(type);
        javaType.parse(field, type, delimiters);
        return javaType;
    }

    /**
     * 类型解析
     *
     * @param field
     * @return
     */
    public static Type parse(TableField field) {
        Type type = get(field.getType());
        if (type != null) {
            try {
                type.parse(field, field.getType(), field.getDelimiters());
            } catch (TypeParseException tpe) {
                throw tpe;
            } catch (Exception e) {
                throw new TypeParseException(String.format("类型解析异常，class:%s, type:%s", type.getClass().getName(), field.getType()), e);
            }
            return type;
        }
        type = getContainerType(field.getType());
        try {
            type.parse(field, field.getType(), field.getDelimiters());
        } catch (TypeParseException tpe) {
            throw tpe;
        } catch (Exception e) {
            throw new TypeParseException(String.format("类型解析异常，class:%s, type:%s", type.getClass().getName(), field.getType()), e);
        }
        return type;
    }


    public static Type.SimpleType getSimpleType(String type) {
        return (Type.SimpleType) TYPES.get(type);
    }

}
